<template>
  <view class="voice-recorder">
    <!-- 语音按钮 -->
    <view 
      class="voice-btn" 
      :class="{ 
        'recording': isRecording, 
        'processing': isProcessing
      }"
      @touchstart="startRecord"
      @touchend="stopRecord"
      @touchcancel="cancelRecord"
    >
      <view class="voice-icon">
        <text v-if="isRecording">🔴</text>
        <text v-else-if="isProcessing">⏳</text>
        <text v-else>🎤</text>
      </view>
      <text class="voice-text">
        {{ voiceButtonText }}
      </text>
      
      <!-- 录音动画 -->
      <view v-if="isRecording" class="recording-animation">
        <view class="wave" v-for="i in 3" :key="i" :class="'wave-' + i"></view>
      </view>
    </view>

    <!-- 使用提示 -->
    <view v-if="!isRecording && !isProcessing && !recognitionResult" class="usage-hint">
      <text class="hint-text">🎤 按住按钮说话，松开完成录音</text>
    </view>
    
    <!-- 语音识别结果 -->
    <view v-if="recognitionResult" class="recognition-result">
      <view class="result-header">
        <text class="result-title">语音识别结果：</text>
        <text class="result-close" @click="clearResult">✕</text>
      </view>
      <text class="result-text">{{ recognitionResult }}</text>
      
      <!-- 解析的信息 -->
      <view v-if="parsedInfo" class="parsed-info">
        <text class="parsed-title">识别到的信息：</text>
        <view class="info-item" v-if="parsedInfo.amount">
          <text class="info-label">奶量：</text>
          <text class="info-value">{{ parsedInfo.amount }}ml</text>
        </view>
        <view class="info-item" v-if="parsedInfo.feedingType">
          <text class="info-label">喂养方式：</text>
          <text class="info-value">{{ feedingTypeNames[parsedInfo.feedingType] }}</text>
        </view>
        <view class="info-item" v-if="parsedInfo.time">
          <text class="info-label">时间：</text>
          <text class="info-value">{{ parsedInfo.time }}</text>
        </view>
        <view class="info-item" v-if="parsedInfo.notes">
          <text class="info-label">备注：</text>
          <text class="info-value">{{ parsedInfo.notes }}</text>
        </view>
        
        <!-- 确认按钮 -->
        <view class="action-buttons">
          <button class="btn-secondary" @click="clearResult">重新录音</button>
          <button class="btn-primary" @click="applyResult">应用到表单</button>
        </view>
      </view>
    </view>
    
    <!-- 错误提示 -->
    <view v-if="errorMessage" class="error-message">
      <view class="error-content">
        <text class="error-text">{{ errorMessage }}</text>
        <text class="error-retry" @click="retryRecognition">点击重试</text>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  name: 'VoiceRecorder',
  props: {
    // 是否禁用
    disabled: {
      type: Boolean,
      default: false
    },
    // 唤起词
    wakeWord: {
      type: String,
      default: '小奶小奶'
    },
    // 是否自动开启监听
    autoListen: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      // 录音状态
      isRecording: false,
      isProcessing: false,
      
      // 识别结果
      recognitionResult: '',
      parsedInfo: null,
      errorMessage: '',
      
      // 语音识别相关
      recognition: null,
      
      // 喂养方式映射
      feedingTypeNames: {
        'direct': '亲喂',
        'bottle_breast': '喝母乳', 
        'bottle_formula': '喝奶粉'
      },
      
      // 超时控制
      recognitionTimeout: null,
      maxRecognitionTime: 15000, // 15秒超时
      
      // 语音合成
      speechSynthesis: null
    }
  },
  
  computed: {
    voiceButtonText() {
      if (this.isRecording) {
        return '正在录音...'
      } else if (this.isProcessing) {
        return '识别中...'
      } else {
        return '按住说话'
      }
    }
  },
  
  mounted() {
    this.initSpeechSynthesis()
  },
  
  // 组件销毁时清理
  beforeDestroy() {
    this.cleanup()
  },
  
  // Vue3兼容
  beforeUnmount() {
    this.cleanup()
  },
  
  methods: {
    // 清理资源
    cleanup() {
      this.clearRecognitionTimeout()
      if (this.recognition) {
        this.recognition.abort()
      }
    },
    
    // 清理识别超时
    clearRecognitionTimeout() {
      if (this.recognitionTimeout) {
        clearTimeout(this.recognitionTimeout)
        this.recognitionTimeout = null
      }
    },
    
    // 初始化语音合成
    initSpeechSynthesis() {
      // #ifdef H5
      if ('speechSynthesis' in window) {
        this.speechSynthesis = window.speechSynthesis
      }
      // #endif
    },
    
    // 智能播报识别结果
    speakRecognitionResult() {
      if (!this.parsedInfo) {
        this.speak('识别完成，请检查结果')
        return
      }
      
      const parts = []
      
      // 按顺序播报：时间/喂养方式/奶量/备注
      if (this.parsedInfo.time) {
        parts.push(`时间：${this.parsedInfo.time}`)
      }
      
      if (this.parsedInfo.feedingType) {
        const typeText = this.feedingTypeNames[this.parsedInfo.feedingType] || this.parsedInfo.feedingType
        parts.push(`喂养方式：${typeText}`)
      }
      
      if (this.parsedInfo.amount) {
        parts.push(`奶量：${this.parsedInfo.amount}毫升`)
      }
      
      if (this.parsedInfo.notes) {
        parts.push(`备注：${this.parsedInfo.notes}`)
      }
      
      if (parts.length > 0) {
        const message = '识别成功，' + parts.join('，')
        this.speak(message)
      } else {
        this.speak('识别完成，但未能解析到有效信息')
      }
    },

    
    // 语音播报
    speak(text, options = {}) {
      console.log('语音播报:', text)
      
      // #ifdef H5
      if (this.speechSynthesis) {
        const utterance = new SpeechSynthesisUtterance(text)
        utterance.lang = 'zh-CN'
        utterance.rate = 1.2
        utterance.pitch = 1.1
        utterance.volume = 0.8
        
        if (options.onend) {
          utterance.onend = options.onend
        }
        
        this.speechSynthesis.speak(utterance)
        return
      }
      // #endif
      
      // #ifdef APP-PLUS
      // App平台使用原生TTS
      if (plus && plus.speech) {
        plus.speech.startSpeak({
          content: text,
          speed: 'normal',
          volume: 0.8
        }, options.onend || (() => {}), (error) => {
          console.error('语音播报失败:', error)
          if (options.onend) options.onend()
        })
        return
      }
      // #endif
      
      // #ifdef MP-WEIXIN  
      // 小程序平台显示文字提示代替语音
      uni.showToast({
        title: text,
        icon: 'none',
        duration: 1500
      })
      if (options.onend) {
        setTimeout(options.onend, 1500)
      }
      // #endif
    },
    

    
    // 开始录音
    startRecord() {
      if (this.disabled || this.isProcessing) return
      
      this.clearResult()
      this.isRecording = true
      this.errorMessage = ''
      
      // 检查录音权限
      this.checkRecordPermission().then(() => {
        // 开始语音识别
        this.startSpeechRecognition()
      }).catch(error => {
        this.isRecording = false
        this.errorMessage = '请授予录音权限后重试'
        console.error('录音权限检查失败:', error)
      })
    },
    
    // 停止录音
    stopRecord() {
      if (!this.isRecording) return
      
      this.isRecording = false
      this.isProcessing = true
      
      // 设置超时保护
      this.setRecognitionTimeout()
      
      // 停止语音识别
      this.stopSpeechRecognition()
    },
    
    // 取消录音
    cancelRecord() {
      this.isRecording = false
      this.isProcessing = false
      this.clearRecognitionTimeout()
      this.stopSpeechRecognition()
    },
    
    // 设置识别超时
    setRecognitionTimeout() {
      this.clearRecognitionTimeout()
      this.recognitionTimeout = setTimeout(() => {
        if (this.isProcessing) {
          this.handleRecognitionError(new Error('语音识别超时，请重试'))
        }
      }, this.maxRecognitionTime)
    },
    
    // 检查录音权限
    checkRecordPermission() {
      return new Promise((resolve, reject) => {
        // #ifdef APP-PLUS
        // App平台检查权限
        const permission = 'android.permission.RECORD_AUDIO'
        plus.android.checkPermission(permission, (hasPermission) => {
          if (hasPermission) {
            resolve()
          } else {
            plus.android.requestPermissions([permission], (e) => {
              if (e.deniedAlways.length > 0) {
                reject(new Error('录音权限被永久拒绝'))
              } else if (e.deniedPresent.length > 0) {
                reject(new Error('录音权限被拒绝'))
              } else {
                resolve()
              }
            })
          }
        })
        // #endif
        
        // #ifdef MP-WEIXIN
        // 微信小程序授权
        uni.authorize({
          scope: 'scope.record',
          success: resolve,
          fail: reject
        })
        // #endif
        
        // #ifdef H5
        // H5平台检查
        if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
          navigator.mediaDevices.getUserMedia({ audio: true })
            .then(resolve)
            .catch(reject)
        } else {
          reject(new Error('浏览器不支持录音功能'))
        }
        // #endif
      })
    },
    
    // 开始语音识别
    startSpeechRecognition() {
      // #ifdef H5
      this.startWebSpeechRecognition()
      // #endif
      
      // #ifdef APP-PLUS
      this.startAppSpeechRecognition()
      // #endif
      
      // #ifdef MP-WEIXIN
      this.startMPSpeechRecognition()
      // #endif
    },
    
    // H5平台Web Speech API识别
    startWebSpeechRecognition() {
      // #ifdef H5
      if (!('webkitSpeechRecognition' in window) && !('SpeechRecognition' in window)) {
        this.handleRecognitionError(new Error('浏览器不支持语音识别，请使用Chrome浏览器'))
        return
      }
      
      const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition
      this.recognition = new SpeechRecognition()
      
      // 识别参数
      this.recognition.lang = 'zh-CN'
      this.recognition.continuous = false
      this.recognition.interimResults = true
      this.recognition.maxAlternatives = 3
      
      // 识别结果处理
      this.recognition.onresult = (event) => {
        let finalTranscript = ''
        
        for (let i = event.resultIndex; i < event.results.length; i++) {
          const transcript = event.results[i][0].transcript.trim()
          if (event.results[i].isFinal) {
            finalTranscript += transcript
          }
        }
        
        if (finalTranscript) {
          this.handleRecognitionSuccess(finalTranscript)
        }
      }
      
      // 错误处理
      this.recognition.onerror = (event) => {
        console.error('Web Speech API错误:', event.error)
        
        let errorMessage = '语音识别失败'
        switch(event.error) {
          case 'no-speech':
            errorMessage = '没有检测到语音，请重试'
            break
          case 'audio-capture':
            errorMessage = '无法访问麦克风，请检查权限'
            break
          case 'not-allowed':
            errorMessage = '麦克风权限被拒绝'
            break
          case 'network':
            errorMessage = '网络错误，请检查网络连接'
            break
          case 'service-not-allowed':
            errorMessage = '语音识别服务不可用'
            break
        }
        
        this.handleRecognitionError(new Error(errorMessage))
      }
      
      this.recognition.start()
      // #endif
    },
    
    // App平台语音识别
    startAppSpeechRecognition() {
      // #ifdef APP-PLUS
      try {
        if (plus && plus.speech) {
          const options = {
            engine: 'iFly',
            lang: 'zh-cn',
            continue: false,
            timeout: 12000,
            punctuation: true
          }
          
          plus.speech.startRecognize(options, (result) => {
            if (result && result.trim()) {
              this.handleRecognitionSuccess(result)
            } else {
              this.handleRecognitionError('未能识别到语音内容，请重试')
            }
          }, (error) => {
            console.error('App语音识别错误:', error)
            let errorMessage = '语音识别失败'
            
            if (error && error.code) {
              switch(error.code) {
                case 10118:
                  errorMessage = '没有检测到语音输入'
                  break
                case 10109:
                  errorMessage = '录音设备不可用'
                  break
                case 10110:
                  errorMessage = '录音权限被拒绝'
                  break
                case 10111:
                  errorMessage = '网络连接失败'
                  break
                default:
                  errorMessage = `识别失败 (${error.code})`
              }
            }
            
            this.handleRecognitionError(new Error(errorMessage))
          })
        } else {
          this.handleRecognitionError(new Error('语音识别功能不可用'))
        }
      } catch (error) {
        this.handleRecognitionError(error)
      }
      // #endif
    },
    
    // 小程序语音识别
    startMPSpeechRecognition() {
      // #ifdef MP-WEIXIN
      try {
        const recorderManager = uni.getRecorderManager()
        
        recorderManager.onStart(() => {
          console.log('小程序开始录音')
        })
        
        recorderManager.onError((error) => {
          console.error('小程序录音错误:', error)
          this.handleRecognitionError('录音失败，请检查麦克风权限')
        })
        
        recorderManager.onStop((res) => {
          console.log('小程序录音结束:', res)
          
          if (!res.tempFilePath) {
            this.handleRecognitionError('录音文件生成失败，请重试')
            return
          }
          
          // 使用云函数进行语音识别（推荐方式）
          this.recognizeVoiceInMP(res.tempFilePath)
        })
        
        recorderManager.start({
          duration: 12000,
          sampleRate: 16000,
          numberOfChannels: 1,
          encodeBitRate: 48000,
          format: 'mp3'
        })
        
        this.recorderManager = recorderManager
        
      } catch (error) {
        console.error('小程序语音识别初始化失败:', error)
        this.handleRecognitionError('语音识别功能不可用')
      }
      // #endif
    },
    
    // 停止语音识别
    stopSpeechRecognition() {
      // #ifdef APP-PLUS
      plus.speech.stopRecognize()
      // #endif
      
      // #ifdef MP-WEIXIN
      const recorderManager = uni.getRecorderManager()
      recorderManager.stop()
      // #endif
      
      // #ifdef H5
      if (this.recognition) {
        this.recognition.stop()
      }
      // #endif
    },
    
    // 处理识别成功
    handleRecognitionSuccess(result) {
      // 清除超时
      this.clearRecognitionTimeout()
      
      this.isProcessing = false
      this.isRecording = false
      this.errorMessage = ''
      
      console.log('语音识别成功:', result)
      this.recognitionResult = result
      
      // 解析语音内容
      this.parseVoiceContent(result)
      
      // 智能播报解析结果
      this.speakRecognitionResult()
      
      // 触发识别完成事件
      this.$emit('recognition-success', {
        text: result,
        parsed: this.parsedInfo
      })
    },
    
    // 处理识别错误
    handleRecognitionError(error) {
      // 清除超时
      this.clearRecognitionTimeout()
      
      this.isProcessing = false
      this.isRecording = false
      
      // 设置错误信息
      if (typeof error === 'string') {
        this.errorMessage = error
      } else if (error && error.message) {
        this.errorMessage = error.message
      } else {
        this.errorMessage = '语音识别失败，请重试'
      }
      
      console.error('语音识别错误:', error)
      
      // 触发错误事件
      this.$emit('recognition-error', error)
      
      // 3秒后自动清除错误信息
      setTimeout(() => {
        this.errorMessage = ''
      }, 3000)
    },
    
    // 解析语音内容 (优化版本)
    parseVoiceContent(text) {
      const parsed = {
        amount: null,
        feedingType: null,
        time: null,
        notes: null
      }
      
      // 优化的奶量解析
      const amountPatterns = [
        /(\d+)\s*(?:毫升|ml|ML|毫升|cc|CC)/i,
        /喂了?\s*(\d+)/,
        /(\d+)\s*(?:的|毫升的)?(?:奶|母乳|奶粉)/i
      ]
      
      for (const pattern of amountPatterns) {
        const match = text.match(pattern)
        if (match) {
          const amount = parseInt(match[1])
          if (amount > 0 && amount <= 500) { // 合理范围检查
            parsed.amount = amount
            break
          }
        }
      }
      
      // 优化的喂养方式解析
      if (text.includes('亲喂') || text.includes('直接喂') || text.includes('亲自喂') || text.includes('亲手喂')) {
        parsed.feedingType = 'direct'
      } else if (text.includes('奶粉') || text.includes('配方奶') || text.includes('冲奶粉')) {
        parsed.feedingType = 'bottle_formula'
      } else if (text.includes('母乳') || text.includes('奶瓶') || text.includes('瓶喂')) {
        parsed.feedingType = 'bottle_breast'
      }
      
      // 优化的时间解析
      const timePatterns = [
        /(?:上午|下午|早上|中午|晚上|凌晨)?\s*(\d{1,2})\s*[点时]\s*(\d{1,2})?\s*[分]?/,
        /(\d{1,2})[：:]\s*(\d{1,2})/,
        /现在|刚才|刚刚/
      ]
      
      for (const pattern of timePatterns) {
        const match = text.match(pattern)
        if (match && match[1]) {
          let hours = parseInt(match[1])
          const minutes = match[2] ? parseInt(match[2]) : 0
          
          // 时间合理性检查
          if (hours >= 0 && hours <= 23 && minutes >= 0 && minutes <= 59) {
            // 处理上午下午
            if (text.includes('下午') || text.includes('晚上')) {
              if (hours < 12) hours += 12
            } else if (text.includes('上午') || text.includes('早上')) {
              if (hours === 12) hours = 0
            }
            
            parsed.time = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`
            break
          }
        } else if (pattern.source.includes('现在')) {
          // 当前时间
          const now = new Date()
          parsed.time = `${now.getHours().toString().padStart(2, '0')}:${now.getMinutes().toString().padStart(2, '0')}`
          break
        }
      }
      
      // 提取备注信息（更智能的清理）
      let notes = text
      
      // 移除已识别的内容
      notes = notes.replace(/\d+\s*(?:毫升|ml|ML|毫升|cc|CC)/gi, '')
      notes = notes.replace(/亲喂|直接喂|亲自喂|亲手喂|奶粉|配方奶|冲奶粉|母乳|奶瓶|瓶喂/g, '')
      notes = notes.replace(/(?:上午|下午|早上|中午|晚上|凌晨)?\s*\d{1,2}\s*[点时]\s*\d{1,2}?\s*[分]?/g, '')
      notes = notes.replace(/\d{1,2}[：:]\s*\d{1,2}/g, '')
      notes = notes.replace(/现在|刚才|刚刚/g, '')
      notes = notes.replace(/给|宝宝|喂了?|喂的|刚刚|刚才|然后|接着/g, '')
      notes = notes.replace(/\s+/g, ' ').trim()
      
      if (notes && notes.length > 1) {
        parsed.notes = notes
      }
      
      this.parsedInfo = parsed
      this.showStatusMessage('语音解析完成', 'success', 2000)
    },
    
    // 小程序语音识别处理
    recognizeVoiceInMP(tempFilePath) {
      // #ifdef MP-WEIXIN
      console.log('开始识别语音文件:', tempFilePath)
      
      // Demo模式：模拟语音识别结果
      setTimeout(() => {
        const demoResults = [
          '给宝宝喂了120毫升母乳下午2点宝宝吃得很香',
          '刚喂了150毫升奶粉现在是上午10点很乖',
          '宝宝亲喂了20分钟晚上8点开始的睡得很好',
          '喂了80毫升母乳中午12点半宝宝很满足',
          '刚才给宝宝喂了180毫升奶粉现在是下午3点',
          '宝宝刚刚亲喂了半小时上午9点开始的'
        ]
        
        const randomResult = demoResults[Math.floor(Math.random() * demoResults.length)]
        
        uni.showToast({
          title: '小程序Demo模式',
          icon: 'none',
          duration: 1000
        })
        
        this.handleRecognitionSuccess(randomResult)
        
      }, 2000)
      
      // 真实语音识别实现示例：
      /*
      // 方案1: 调用云函数处理语音识别
      uniCloud.callFunction({
        name: 'voice-recognition',
        data: {
          voiceFilePath: tempFilePath
        }
      }).then(result => {
        if (result.result && result.result.text) {
          this.handleRecognitionSuccess(result.result.text)
        } else {
          this.handleRecognitionError('语音识别失败')
        }
      }).catch(error => {
        this.handleRecognitionError('语音识别服务异常: ' + error.message)
      })
      
      // 方案2: 使用腾讯云语音识别插件
      // wx.cloud.callFunction({
      //   name: 'speechRecognition',
      //   data: {
      //     filePath: tempFilePath
      //   }
      // })
      */
      
      // #endif
    },

    // 清除结果
    clearResult() {
      this.recognitionResult = ''
      this.parsedInfo = null
      this.errorMessage = ''
      this.statusMessage = ''
    },
    
    // 应用结果到表单
    applyResult() {
      this.$emit('apply-result', this.parsedInfo)
      this.clearResult()
      this.showStatusMessage('数据已应用到表单', 'success', 2000)
      
      // 语音确认
      this.speak('数据已应用')
    },
    
    // 重试语音识别
    retryRecognition() {
      this.clearResult()
      this.errorMessage = ''
      
      uni.showToast({
        title: '请重新录音',
        icon: 'none',
        duration: 1000
      })
      

    }
  }
}
</script>

<style scoped>
.voice-recorder {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.voice-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 120rpx;
  height: 120rpx;
  background: linear-gradient(135deg, #ff6b9d, #ff8a9b);
  border-radius: 60rpx;
  position: relative;
  transition: all 0.3s ease;
  box-shadow: 0 8rpx 20rpx rgba(255, 107, 157, 0.3);
}

.voice-btn.recording {
  background: linear-gradient(135deg, #ff4757, #ff6348);
  transform: scale(1.1);
  box-shadow: 0 12rpx 30rpx rgba(255, 71, 87, 0.4);
}

.voice-btn.processing {
  background: linear-gradient(135deg, #ffa726, #ffb74d);
  animation: pulse 1.5s infinite;
}



.voice-icon {
  font-size: 48rpx;
  margin-bottom: 8rpx;
}

.voice-text {
  font-size: 20rpx;
  color: white;
  font-weight: bold;
}

.recording-animation {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 200rpx;
  height: 200rpx;
  pointer-events: none;
}

.wave {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  border: 3rpx solid rgba(255, 255, 255, 0.3);
  border-radius: 50%;
  animation: wave-animation 2s infinite;
}

.wave-1 {
  animation-delay: 0s;
}

.wave-2 {
  animation-delay: 0.7s;
}

.wave-3 {
  animation-delay: 1.4s;
}

@keyframes wave-animation {
  0% {
    width: 120rpx;
    height: 120rpx;
    opacity: 1;
  }
  100% {
    width: 200rpx;
    height: 200rpx;
    opacity: 0;
  }
}

@keyframes pulse {
  0% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.05);
  }
  100% {
    transform: scale(1);
  }
}



.recognition-result {
  margin-top: 30rpx;
  background-color: #f8f9fa;
  border-radius: 16rpx;
  padding: 24rpx;
  border: 1rpx solid #e9ecef;
}

.result-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16rpx;
}

.result-title {
  font-size: 28rpx;
  font-weight: bold;
  color: #333;
}

.result-close {
  font-size: 32rpx;
  color: #999;
  padding: 8rpx;
}

.result-text {
  font-size: 26rpx;
  color: #666;
  line-height: 1.5;
  margin-bottom: 20rpx;
  display: block;
}

.parsed-info {
  border-top: 1rpx solid #e9ecef;
  padding-top: 20rpx;
}

.parsed-title {
  font-size: 26rpx;
  font-weight: bold;
  color: #333;
  margin-bottom: 16rpx;
  display: block;
}

.info-item {
  display: flex;
  margin-bottom: 12rpx;
}

.info-label {
  font-size: 24rpx;
  color: #666;
  width: 120rpx;
  flex-shrink: 0;
}

.info-value {
  font-size: 24rpx;
  color: #333;
  font-weight: bold;
}

.action-buttons {
  display: flex;
  gap: 20rpx;
  margin-top: 24rpx;
}

.btn-secondary,
.btn-primary {
  flex: 1;
  height: 72rpx;
  border-radius: 36rpx;
  font-size: 28rpx;
  font-weight: bold;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
}

.btn-secondary {
  background-color: #f8f9fa;
  color: #666;
  border: 1rpx solid #e9ecef;
}

.btn-primary {
  background: linear-gradient(135deg, #ff6b9d, #ff8a9b);
  color: white;
}

.error-message {
  margin-top: 20rpx;
  padding: 20rpx;
  background-color: #fff5f5;
  border: 1rpx solid #fed7d7;
  border-radius: 12rpx;
}

.error-content {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12rpx;
}

.error-text {
  color: #e53e3e;
  font-size: 24rpx;
  text-align: center;
  line-height: 1.4;
}

.error-retry {
  color: #ff6b9d;
  font-size: 26rpx;
  font-weight: bold;
  padding: 8rpx 20rpx;
  background-color: rgba(255, 107, 157, 0.1);
  border-radius: 20rpx;
  border: 1rpx solid #ff6b9d;
}

.error-retry:active {
  background-color: rgba(255, 107, 157, 0.2);
  transform: scale(0.95);
}

.usage-hint {
  margin-top: 20rpx;
  padding: 20rpx;
  background-color: #f8f9fa;
  border: 1rpx solid #e9ecef;
  border-radius: 12rpx;
}

.hint-text {
  color: #666;
  font-size: 24rpx;
  text-align: center;
  line-height: 1.4;
}
</style> 